
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
	<title>filefind</title>
    <link rel="stylesheet" href="doc.css" type="text/css"/>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>

<body>

<div id="container">

<div id="product">

	<div id="product_name"><big><strong>filefind</strong></big></div>
	<div id="product_description">Directory iteration and file globs</div>
</div> <!-- id="product" -->

<div id="main">

<div id="navigation">
<h1>filefind</h1>
	<ul>

		<li><strong>Home</strong>
			<ul>
                            
			</ul>
		</li>

	</ul>
</div> <!-- id="navigation" -->

<div id="content">


<h2>Overview</h2>

<p><em>filefind</em> is a Lua module providing both highly efficient directory iteration and an expressive syntax for recursively globbing sets of files or directories from the disk in a single execution.  The globbing functionality was inspired by Perforce's recursive wildcard syntax and implements JPSoft's TCC syntax for stepping up directories.</p>

<h2>Example</h2>


<pre>
    filefind = require 'filefind'

    for entry in filefind.glob('**') do
        print(entry.filename)
    end
</pre>



<h2>Reference Manual</h2>

<p>This is a reference of all of the <em>filefind</em> module's methods.</p>

<h2>Module <code>filefind</code></h2>

<p><strong>entryTable = filefind.attributes(<em>filename</em>)</strong></p>

<p>Retrieves file or directory properties for one item.</p>


<p><strong>for entry in filefind.glob(<em>pattern</em>) do</strong></p>

<p>Begins a new iteration of files and/or directories using <em>pattern</em> as the glob wildcard.  All glob syntax, described elsewhere, is available.</p>


<p><strong>for entry in filefind.match(<em>pattern</em>) do</strong></p>

<p>Begins a new iteration of files and directories using <em>pattern</em> as the wildcard.  Simple access to the file system is used.  The more powerful file globbing facilities are not available.</p>


<p><strong>matches = filefind.pattern_match(<em>pattern</em>, <em>string</em>, <em>caseSensitive</em> = false, <em>recursive</em> = true) do</strong></p>

<p>Tests <code>string</code> against <code>pattern</code> to determine a match.  The syntax for <code>pattern</code> follows the wildcard globbing syntax described elsewhere in this document.</p>

<p>Pass <code>true</code> for <code>caseSensitive</code> to perform a search where case sensitivity matters.  The default is <code>false</code>.</p>

<p>Pass <code>true</code> for <code>recursive</code> to perform a search where directory separators are tested and <code>**</code> will work across directory separator boundaries.  Pass <code>false</code> to use <code>*</code> to search across the entire <code>string</code>.</p>



<h3>Time Conversion</h3>

<p><strong>lowTime, highTime = filefind.unix_time_to_FILETIME_UTC(unixTime)</strong></p>

<p>Converts a Unix time_t to a Windows FILETIME adjusted to UTC.  Returns the FILETIME as a two integers representing low time and high time.</p>


<p><strong>entryTable = filefind.unix_time_to_FILETIME_UTC(unixTime)</strong></p>

<p>Converts a Unix time_t to a Windows FILETIME adjusted to UTC.  Returns the FILETIME as a two integers representing low time and high time.</p>


<p><strong>entryTable = filefind.FILETIME_to_unix_time_UTC(filetime)</strong></p>

<p>Converts a Windows FILETIME to Unix time_t adjusted to UTC.  <code>filetime</code> may be two integers representing the low time and high time of the FILETIME structure or a string representing the low time and high time combined.</p>

<p>Returns the time_t.</p>


<p><strong>entryTable = filefind.time_t_to_FILETIME(time_t)</strong></p>

<p>Converts a Unix time_t to a Windows FILETIME.  Returns the FILETIME as a two integers representing low time and high time.</p>


<p><strong>entryTable = filefind.FILETIME_to_time_t(filetime)</strong></p>

<p>Converts a Windows FILETIME to Unix time_t.  <code>filetime</code> may be two integers representing the low time and high time of the FILETIME structure or a string representing the low time and high time combined.</p>

<p>Returns the time_t.</p>




<h3>File entry information</h3>

<p><strong>entry.table</strong> - table - Returns a table with all of the properties below.  Entry properties are usually looked up and returned on demand.  Some may take extra time to compute.</p>

<p><strong>entry.filename</strong> - string - The relative path from the <em>filefind.match()</em> starting directory.</p>

<p><strong>entry.creation_time</strong> - number - The creation time of the file/directory in seconds starting from midnight (00:00:00), January 1, 1970.</p>

<p><strong>entry.access_time</strong> - number - The last access time of the file/directory in seconds starting from midnight (00:00:00), January 1, 1970.</p>

<p><strong>entry.write_time</strong> - number - The last write time of the file/directory in seconds starting from midnight (00:00:00), January 1, 1970.</p>

<p><strong>entry.creation_FILETIME</strong> - table - The creation time of the file/directory in FILETIME format starting from midnight (00:00:00), January 1, 1970.  Element 1 of the table is the low file time.  Element 2 is the high file time.</p>

<p><strong>entry.access_FILETIME</strong> - table - The last access time of the file/directory in FILETIME format starting from midnight (00:00:00), January 1, 1970.  Element 1 of the table is the low file time.  Element 2 is the high file time.</p>

<p><strong>entry.write_FILETIME</strong> - table - The last write time of the file/directory in FILETIME format starting from midnight (00:00:00), January 1, 1970.  Element 1 of the table is the low file time.  Element 2 is the high file time.</p>

<p><strong>entry.is_directory</strong> - boolean - <tt>true</tt> if the glob entry is a directory, <tt>false</tt> otherwise.</p>

<p><strong>entry.is_link</strong> - boolean - <tt>true</tt> if the entry is a hard or symbolic link, <tt>false</tt> otherwise.</p>

<p><strong>entry.is_readonly</strong> - boolean - <tt>true</tt> if the glob entry is read only, <tt>false</tt> otherwise.</p>

<p><strong>entry.number<em>of</em>links</strong> - number - The number of files pointing to the hardlink blob, 0 if none.</p>

<p><strong>entry.size</strong> - number - The size of the file.</p>



<h2>Available Glob Syntax</h2>


<table border="1" width="75%" align="center">
  <tr>

    <td width="150"><b>Wildcard</b></td>
    <td width="450"><b>Description</b></td>
  </tr>
  <tr>
    <td><code>?</code></td>
    <td>Matches any single character of the file name or directory name.</td>
  </tr>

  <tr>
    <td><code>*</code></td>
    <td>Matches 0 or more characters of the file name or directory name.</td>
  </tr>
  <tr>
    <td><code>/</code> at end of pattern</td>
    <td>Any pattern with a closing slash will start a directory search, instead of the default file search.</td>
  </tr>
  <tr>
    <td><code>**</code></td>
    <td>Search files recursively.</td>
  </tr>
  <tr>
    <td><code>**/</code></td>
    <td>Search directories recursively.</td>
  </tr>
</table>



<p>Some examples follow:</p>



<table border="1" width="75%"  align="center">
  <tr>
    <td width="150"><b>Example Pattern</b></td>
    <td width="450"><b>Description</b></td>
  </tr>

  <tr>
    <td><code>File.txt</code></td>
    <td>Matches a file or directory called <i>File.txt</i>.</td>
  </tr>
  <tr>
    <td><code>File*.txt</code></td>

    <td>Matches any file or directory starting with File and ending with a .txt extension.</td>
  </tr>
  <tr>
    <td><code>File?.txt</code></td>
    <td>Matches any file or directory starting with File and containing one more character.</td>
  </tr>
  <tr>
    <td><code>F??e*.txt</code></td>
    <td>Matches a file or directory starting with F, followed by any two characters, followed by e, then any number of characters up to the extension .txt.</td>
  </tr>
  <tr>
    <td><code>File*</code></td>
    <td>Matches a file or directory starting with File and ending with or without an extension.</td>
  </tr>

  <tr>
    <td><code>*</code></td>
    <td>Matches all files (non-recursive).</td>
  </tr>
  <tr>
    <td><code>*/</code></td>
    <td>Matches all directories (non-recursive).</td>

  </tr>
  <tr>
    <td><code>A*/</code></td>
    <td>Matches any directory starting with A (non-recursive).</td>
  </tr>
  <tr>
    <td><code>**/*</code></td>

    <td>Matches all files (recursive).</td>
  </tr>
  <tr>
    <td><code>**</code></td>
    <td>Shortened form of above. Matches all files (recursive). Internally, expands to **/*</td>
  </tr>
  <tr>

    <td><code>**/</code></td>
    <td>Matches all directories (recursive).</td>
  </tr>
  <tr>
    <td><code>**{filename chars}</code></td>
    <td>Matches {filename chars} recursively. Internally, expands to **/*{filename chars}.</td>
  </tr>

  <tr>
    <td><code>{dirname chars}**</code></td>
    <td>Expands to {dirname chars}*/**.</td>
  </tr>
  <tr>
    <td><code>{dirname chars}**{filename chars}</code></td>
    <td>Expands to {dirname chars}*/**/*{filename chars}.</td>

  </tr>
  <tr>
    <td><code>**.h</code></td>
    <td>Matches all *.h files recursively. Expands to **/*.h.</td>
  </tr>
  <tr>
    <td><code>**resource.h</code></td>

    <td>Matches all *resource.h files recursively.
    Expands to **/*resource.h.</td>
  </tr>
  <tr>
    <td><code>BK**</code></td>
    <td>Matches all files in any directory starting with BK, recursively. Expands to BK*/**.</td>
  </tr>
  <tr>

    <td><code>BK**.h</code></td>
    <td>Matches all *.h files in any directory starting with BK, recursively. Expands to BK*/**/*.h.</td>
  </tr>
  <tr>
    <td><code>c:/Src/**/*.h</code></td>
    <td>Matches all *.h files recursively, starting at c:/Src/.</td>
  </tr>
  <tr>
    <td><code>c:/Src/**/*Grid/</code></td>
    <td>Recursively matches all directories under c:/Src/ that end with Grid.</td>
  </tr>
  <tr>
    <td><code>c:/Src/**/*Grid*/</code></td>
    <td>Recursively matches all directories under c:/Src/ that contain Grid.</td>
  </tr>
  <tr>
    <td><code>c:/Src/**/*Grid*/**/ABC/**/Readme.txt</code></td>

    <td>Recursively matches all directories under c:/Src/ that contain Grid. From the found directory, recursively matches directories until ABC/ is found. From there, the file <i>Readme.txt</i> is searched for recursively. </td>
  </tr>
</table>



<p>Finally, a couple flags are available. Flags are appended at the end of the pattern line. Each flag begins with an @ character. Spaces should not be inserted between flags unless they are intended as part of the string literal.</p>



<table border="1" width="75%" align="center">
  <tr>
    <td width="150"><b>Flags and Other Expansions</b></td>
    <td width="450"><b>Description</b></td>
  </tr>
  <tr>
    <td><code>@*</code></td>
    <td>Search files and directories recursively.</td>
  </tr>
  <tr>
    <td><code>@-pattern</code></td>
    <td>Adds <code>pattern</code> to the file ignore list. Any file matching a pattern in the file ignore list is removed from the search.</td>
  </tr>
  <tr>
    <td><code>@-pattern/</code></td>
    <td>Adds <code>pattern/</code> to the directory ignore list. Any directory matching a pattern in the directory ignore list is removed from the search.</td>
  </tr>
  <tr>
    <td><code>@=pattern</code></td>
    <td>Adds <code>pattern</code> to the exclusive file list. Any file not matching a pattern in the exclusive file list is automatically removed from the search.</td>
  </tr>
  <tr>
    <td><code>@=pattern/</code></td>
    <td>Adds <code>pattern/</code> to the exclusive directory list. Any directory not matching a pattern in the exclusive file list is automatically removed from the search.</td>
  </tr>
  <tr>
    <td>More than two periods for going up parent directories.</td>
    <td>Similar to 4DOS, each period exceeding two periods goes up one additional parent directory. So, a 4 period path expands to <code>../../../.</code></td>
  </tr>
</table>


<p>Wildcards may appear anywhere in the pattern, including directories.</p>

<pre><code>*/*/*/*.c
</code></pre>

<p>Note that <em>.</em> only matches files that have an extension.  This is different than standard DOS behavior.  Use * all by itself to match files, extension or not.</p>

<p>Recursive wildcards can be used anywhere:</p>

<pre><code>c:/Dir1/**/A*/**/FileDirs*/**.mp3
</code></pre>

<p>This matches all directories under c:/Dir1/ that start with A.  Under all of the directories that start with A, directories starting with FileDirs are matched recursively.  Finally, all files ending with an mp3 extension are matched.</p>


<p>A few examples:</p>



<table border="1" width="75%" align="center">
  <tr>
    <td width="150"><b>Example Pattern</b></td>
    <td width="450"><b>Description</b></td>
  </tr>
  <tr>
    <td><code>Src/**/@-**/.git/@-**/.svn/</code></td>
    <td>Recursively lists all directories under Src/, but directories called .git/ and .svn/ are filtered.</td>
  </tr>
  <tr>
    <td><code>Src/**@=**.lua@=**/README</code></td>
    <td>Recursively lists all files under Src/ which match *.lua or README. All other files are ignored.</td>
  </tr>
  <tr>
    <td><code>Src/**/@-**/.git/@-**/.svn/@=**.lua@=**/README</code></td>
    <td>Recursively lists all files under Src/ which match *.lua or README. The versions of those files that may exist in .git/ or .svn/ are ignored.</td>
  </tr>
  <tr>
    <td><code>...../StartSearchHere/**</code></td>
    <td>Expands to: ../../../../StartSearchHere/**</td>
  </tr>
</table>




<h2>License</h2>

<p>The filefind module is licensed under the terms of the MIT and BSD licenses.</p>


<h2>Credits</h2>

<p>The filefind module glob source code was originally based on <a href="http://www.sentex.net/~mwandel/jhead/">Matthias Wandel's MyGlob</a> code, used in his Exif Jpeg camera setting parser and thumbnail remover application.  It also expands upon the <a href="http://www.codeproject.com/string/wildcmp.asp">wildcmp()</a> code written by Jack Handy.</p>

<p>For version 3.0, the MyGlob implementation was replaced with Ruby's faster implementation found in dir.c of the Ruby source code distribution.</p>

<p>Joshua Jensen wrote the rest of the filefind module.</p>


<h2>History</h2>

<ul>
    <li><p>Version 3.0 (23 Jan 2014)</p>
    <ul>
        <li>Updated to Ruby's dir.c glob() implementation.</li>
        <li>The @- and @= modifiers use a recursive pattern matching syntax.</li>
    </ul></li>
    <li><p>Version 2.0 (9 Dec 2009)</p>
    <ul>
        <li>Adds a revamped version of the old 'glob' module that handles iterators and has even better performance.  Also adds support for the <tt>+</tt> modifier that will list both files and directories.</li>
        <li>Changes the access functions to just member lookups for the resultant handle.</li>
        <li>A number of bug fixes.</li>
    </ul></li>
    <li><p>Version 1.0 (27 Aug 2002 - CodeProject article at http://www.codeproject.com/KB/files/fileglob.aspx)</p>
    <ul>
        <li>Initial version.</li>
    </ul></li>
</ul>





</div> <!-- id="content" -->

</div> <!-- id="main" -->

<div id="about">
	<p><a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.0!</a></p>
</div> <!-- id="about" -->

</div> <!-- id="container" -->

</body>
</html>

